<template>
  <div class="rich-text-editor">
    <!-- 工具栏 -->
    <div v-if="toolbarConfig.show" class="toolbar">
      <!-- 工具栏分组 -->
      <div 
        v-for="group in toolbarGroups" 
        :key="group.name"
        class="toolbar-group"
      >
        <div class="group-tools">
          <button 
            v-for="toolName in group.tools" 
            :key="toolName"
            @click="doExecuteCommand(toolDefinitions[toolName].command)"
            :class="{ 
              active: doIsActive(toolDefinitions[toolName].command),
              'recording': toolName === 'voiceToText' && doIsRecording(),
              'processing': toolName === 'voiceToText' && doIsProcessing(),
              'disabled': (doIsRecording() || doIsProcessing()) && toolName !== 'voiceToText'
            }"
            :title="doGetToolTitle(toolName)"
            class="tool-btn"
            :disabled="(doIsRecording() || doIsProcessing()) && toolName !== 'voiceToText'"
          >
            <i :class="toolDefinitions[toolName].icon" v-if="!(toolName === 'voiceToText' && doIsRecording())"></i>
            <!-- 录音波浪动效 -->
            <div v-if="toolName === 'voiceToText' && doIsRecording()" class="wave-animation">
              <div class="wave-bar" v-for="i in 5" :key="i"></div>
            </div>
            <!-- 解析状态指示 -->
            <div v-if="toolName === 'voiceToText' && doIsProcessing()" class="processing-indicator"></div>
          </button>
        </div>
        <div class="group-separator"></div>
      </div>
      
      <!-- 字体大小选择 -->
      <div v-if="showFontSize" class="toolbar-group">
        <CustomDropdown
          v-model="selectedFontSize"
          :options="fontSizeOptions"
          placeholder="字体大小"
          width="80px"
          @change="doOnFontSizeChange"
        />
        <div class="group-separator"></div>
      </div>
      
      <!-- 字体选择 -->
      <div v-if="showFontFamily" class="toolbar-group">
        <CustomDropdown
          v-model="selectedFontFamily"
          :options="fontFamilyOptions"
          placeholder="字体"
          width="100px"
          @change="doOnFontFamilyChange"
        />
        <div class="group-separator"></div>
      </div>
      
      <!-- 颜色选择器 -->
      <div v-if="showColors" class="toolbar-group">
        <!-- 文字颜色选择 -->
        <div v-if="showTextColor" class="color-btn-wrapper">
          <button class="color-btn text-color-btn" :style="{ borderBottom: '5px solid ' + textColor }" type="button">
            <i class="sjqeditor _wenziyanse"></i>
            <input
              ref="textColorInput"
              type="color"
              v-model="textColor"
              @input="doOnTextColorChange"
              class="color-input-overlay"
              title="文字颜色"
            />
          </button>
        </div>
        <!-- 背景颜色选择 -->
        <div v-if="showBackgroundColor" class="color-btn-wrapper">
          <button class="color-btn bg-color-btn" :style="{ borderBottom: '5px solid ' + backgroundColor }" type="button">
            <i class="sjqeditor _beijingyanse"></i>
            <input
              ref="bgColorInput"
              type="color"
              v-model="backgroundColor"
              @input="doOnBgColorChange"
              class="color-input-overlay"
              title="背景颜色"
            />
          </button>
        </div>
        <div class="group-separator"></div>
      </div>
    </div>
    
    <!-- 编辑区域 -->
    <div 
      ref="editor"
      class="editor-content"
      contenteditable="true"
      @input="handleInput"
      @keydown="handleKeydown"
      @paste="handlePaste"
      @focus="handleFocus"
      @blur="handleBlur"
      @selectstart="handleSelectStart"
      @selectionchange="handleSelectionChange"
      @mouseup="handleMouseUp"
      @scroll="handleEditorScroll"
      @click="handleEditorClick"
      :data-placeholder="placeholder"
    ></div>
    
    <!-- 字数统计 -->
    <div class="word-count">
      字数: {{ wordCount }}
    </div>
    
    <!-- 表格插入组件 -->
    <TableInsert 
      :visible="showTableInsert"
      @insert-table="doInsertTableHTML"
      @close="showTableInsert = false"
    />
    
    <!-- iframe插入组件 -->
    <IframeInsert 
      :visible="showIframeInsert"
      @insert-iframe="doInsertIframeHTML"
      @close="showIframeInsert = false"
    />
    
    <!-- 文本选择工具栏 -->
    <TextSelectionToolbar
      :visible="showTextToolbar"
      :selected-text="selectedText"
      :position="textToolbarPosition"
      :trigger-comment="triggerComment"
      @rewrite="handleTextRewrite"
      @continue="handleTextContinue"
      @abbreviate="handleTextAbbreviate"
      @translate="handleTextTranslate"
      @spell-check="handleTextSpellCheck"
      @sensitive-check="handleTextSensitiveCheck"
      @grammar-check="handleTextGrammarCheck"
      @comment="handleTextComment"
      @submit-comment="doHandleSubmitComment"
      @comment-mode-enter="handleCommentModeEnter"
      @comment-mode-exit="handleCommentModeExit"
    />
    
    <!-- 批注内容容器 -->
    <div 
      v-for="comment in comments" 
      :key="comment.id"
      v-show="showComments"
      class="comment-content"
      :style="comment.style"
      @mouseenter="doHighlightCommentArea(comment)"
      @mouseleave="doUnhighlightCommentArea(comment)"
    >
      <div class="comment-header">
        <div class="comment-info">
          <div class="comment-meta">
            <span class="comment-username">{{ comment.username }}</span>
            <span class="comment-time">{{ comment.time }}</span>
          </div>
        </div>
        <button class="comment-close" @click="doRemoveComment(comment.id)">×</button>
      </div>
      <div class="comment-text">{{ comment.text }}</div>
    </div>

    <!-- 改写结果弹窗 -->
    <RewriteResultDialog
      :visible="rewriteResultVisible"
      :original-text="rewriteData.originalText"
      :result-text="rewriteData.resultText"
      :position="rewriteToolbarPosition"
      :function-type="rewriteData.functionType"
      @close="closeRewriteResult"
      @cancel="closeRewriteResult"
      @apply="handleApplyRewrite"
      @back-to-toolbar="handleBackToToolbar"
    />
  </div>
</template>

<script>
import TableInsert from './TableInsert.vue'
import TextSelectionToolbar from './TextSelectionToolbar.vue'
import CustomDropdown from './components/Dropdown.vue'
import IframeInsert from './components/IframeInsert.vue'
import RewriteResultDialog from '../dialog/RewriteResultDialog.vue'
import { useComment } from './composables/useComment'
import { useToolbar } from './composables/useToolbar'
import { textProcessingAPI } from './api/textProcessingAPI'

export default {
  components: {
    TableInsert,
    TextSelectionToolbar,
    CustomDropdown,
    IframeInsert,
    RewriteResultDialog
  },
  name: 'RichTextEditor',
  props: {
    value: {
      type: String,
      default: ''
    },
    placeholder: {
      type: String,
      default: '请输入内容...'
    },
    readonly: {
      type: Boolean,
      default: false
    },
    fullHeight: {
      type: Boolean,
      default: false
    },
    // 工具栏配置
    toolbarConfig: {
      type: Object,
      default: () => ({
        // 是否显示工具栏
        show: true,
        // 工具栏分组配置
        groups: [
          {
            name: 'text',
            title: '文本格式',
            tools: ['bold', 'italic', 'underline', 'strikethrough']
          },
          {
            name: 'align',
            title: '对齐方式',
            tools: ['justifyLeft', 'justifyCenter', 'justifyRight', 'justifyFull']
          },
          // {
          //   name: 'insert',
          //   title: '插入',
          //   tools: ['createLink', 'insertImage']
          // },
          {
            name: 'insert',
            title: '插入',
            tools: ['insertTable', 'insertIframe', 'voiceToText']
          },
          {
            name: 'action',
            title: '操作',
            tools: ['undo', 'redo', 'clear', 'comment', 'toggleComments']
          }
        ],
        // 字体大小选择器
        fontSize: {
          show: true,
          options: [
            { value: '1', label: '12px' },
            { value: '2', label: '14px' },
            { value: '3', label: '16px' },
            { value: '4', label: '18px' },
            { value: '5', label: '20px' },
            { value: '6', label: '24px' },
            { value: '7', label: '36px' }
          ]
        },
        // 字体选择器
        fontFamily: {
          show: true,
          options: [
            { value: '1', label: '微软雅黑' },
            { value: '2', label: '宋体' },
            { value: '3', label: '仿宋' },
            { value: '4', label: '楷体' },
            { value: '5', label: '黑体' }
          ]
        },
        // 颜色选择器
        colors: {
          show: true,
          textColor: true,
          backgroundColor: true
        }
      })
    }
  },
  data() {
    return {
      content: '',
      wordCount: 0,
      isInternalUpdate: false, // 标记是否为内部更新
      // 文本选择相关状态
      hasSelection: false,
      selectedText: '',
      selectionRange: null,
      // 简单的localStorage保存
      savedSelection: null,
      // 文本选择工具栏状态
      showTextToolbar: false,
      textToolbarPosition: { x: 0, y: 0 },
      // 改写结果弹窗状态
      rewriteResultVisible: false,
      rewriteData: {
        originalText: '',
        resultText: '',
        functionType: 'rewrite' // 'rewrite' 或 'continue'
      },
      rewriteToolbarPosition: { x: 0, y: 0 }
    }
  },
  setup() {
    // 使用批注相关的 composable
    const commentComposable = useComment()
    
    // 使用工具栏相关的 composable
    const toolbarComposable = useToolbar()

    return {
      ...commentComposable,
      ...toolbarComposable
    }
  },
  computed: {
    // 获取工具栏分组
    toolbarGroups() {
      if (!this.toolbarConfig.show) return []
      return this.toolbarConfig.groups || []
    },
    
    // 获取字体大小选项
    fontSizeOptions() {
      return this.toolbarConfig.fontSize?.options || []
    },
    
    // 是否显示字体大小选择器
    showFontSize() {
      return this.toolbarConfig.fontSize?.show !== false
    },
    
    // 获取字体选项
    fontFamilyOptions() {
      return this.toolbarConfig.fontFamily?.options || []
    },
    
    // 是否显示字体选择器
    showFontFamily() {
      return this.toolbarConfig.fontFamily?.show !== false
    },
    
    // 是否显示颜色选择器
    showColors() {
      return this.toolbarConfig.colors?.show !== false
    },
    
    // 是否显示文字颜色选择器
    showTextColor() {
      return this.toolbarConfig.colors?.textColor !== false
    },
    
    // 是否显示背景颜色选择器
    showBackgroundColor() {
      return this.toolbarConfig.colors?.backgroundColor !== false
    },
    

  },
  watch: {
    value: {
      immediate: true,
      handler(newVal) {
        // 如果是内部更新触发的，跳过处理
        if (this.isInternalUpdate) {
          return
        }
        
        // 确保 newVal 是字符串
        if (typeof newVal === 'string') {
          // 检查内容是否真的发生了变化，避免不必要的更新
          if (newVal !== this.content) {
            this.content = newVal || ''
            this.$nextTick(() => {
              if (this.$refs.editor) {
                // 保存当前光标位置
                const selection = window.getSelection()
                const range = selection.rangeCount > 0 ? selection.getRangeAt(0) : null
                const wasAtEnd = range && range.collapsed && range.startOffset === range.endOffset
                
                this.$refs.editor.innerHTML = this.content
                
                // 恢复光标位置
                if (range && this.$refs.editor.contains(range.commonAncestorContainer)) {
                  try {
                    selection.removeAllRanges()
                    selection.addRange(range)
                  } catch (e) {
                    // 如果恢复失败，将光标移到末尾
                    this.moveCursorToEnd()
                  }
                } else if (wasAtEnd) {
                  // 如果之前在末尾，现在也移到末尾
                  this.moveCursorToEnd()
                }
                
                this.updateWordCount()
                this.updatePlaceholder()
              }
            })
          }
        }
      }
    },
    content(newVal) {
      // 避免循环触发，只在内容真正改变时发送事件
      if (typeof newVal === 'string' && newVal !== this.value) {
        this.$emit('input', newVal)
      }
      this.updateWordCount()
    }
  },
  mounted() {
    // 确保初始内容正确设置
    if (this.value && this.$refs.editor) {
      this.content = this.value
      this.$refs.editor.innerHTML = this.content
    }
    
    this.updateWordCount()
    this.updatePlaceholder()
    
    if (this.readonly) {
      this.$refs.editor.setAttribute('contenteditable', 'false')
    }
    
    // 初始化激活状态缓存
    this.$nextTick(() => {
      this.updateActiveStates()
      // 从localStorage恢复选择
      this.restoreSelection()
    })
    
    // 添加全局点击事件监听，点击外部区域隐藏工具栏
    document.addEventListener('click', this.handleGlobalClick)
    
    // 初始化滚动位置
    this.lastScrollTop = this.$refs.editor ? this.$refs.editor.scrollTop : 0
    
    // 设置变量编辑状态监听器
    this.$nextTick(() => {
      if (this.$refs.editor) {
        this.setupVariableEditListener(this.$refs.editor, this.updateContent)
        
        // 为现有的iframe添加拖拽事件
        this.addIframeResizeEvents(this.$refs.editor, this.updateContent)
      }
    })
    

  },
  
  beforeDestroy() {
    // 移除全局点击事件监听
    document.removeEventListener('click', this.handleGlobalClick)
    
    // 移除变量编辑监听器
    if (this.$refs.editor && this.$refs.editor._variableEditListener) {
      this.$refs.editor.removeEventListener('input', this.$refs.editor._variableEditListener)
    }
  },
  methods: {
    // 工具栏相关包装方法
    doGetToolTitle(toolName) {
      return this.getToolTitle(toolName)
    },
    
    doExecuteCommand(command, value = null) {
      this.executeCommand(command, value, this.$refs.editor, this.updateContent, this.readonly, this.handleToolbarComment, this.handleToggleComments)
    },
    
    doIsActive(command, value = null) {
      return this.isActive(command, value, this.readonly, this.showComments)
    },
    
    doOnTextColorChange(e) {
      this.onTextColorChange(e, this.doExecuteCommand)
    },
    
    doOnBgColorChange(e) {
      this.onBgColorChange(e, this.doExecuteCommand)
    },
    
    doOnFontSizeChange(option) {
      this.onFontSizeChange(option, this.setFontSize, this.$refs.editor, this.updateContent)
    },
    
    doOnFontFamilyChange(option) {
      this.onFontFamilyChange(option, this.setFontFamily, this.$refs.editor, this.updateContent)
    },
    
    doInsertTableHTML(tableHTML) {
      this.insertTableHTML(tableHTML, this.$refs.editor, this.updateContent)
    },
    
    doInsertIframeHTML(iframeHTML) {
      this.insertIframeHTML(iframeHTML, this.$refs.editor, this.updateContent)
    },
    
    // 录音状态相关方法
    doIsRecording() {
      return this.isRecording
    },
    
    doIsProcessing() {
      return this.isProcessing
    },
    
    // 变量相关方法 - 供父组件调用
    getVariables() {
      return this.exportAllVariables(this.$refs.editor)
    },
    
    getVariableConfigData() {
      return this.getVariableConfig(this.$refs.editor)
    },
    
    updateVariable(variableId, newContent) {
      return this.updateVariableContent(this.$refs.editor, variableId, newContent)
    },
    
    removeVariableById(variableId) {
      return this.removeVariable(this.$refs.editor, variableId)
    },
    

    
    // 处理输入事件
    handleInput(event) {
      this.isInternalUpdate = true
      this.updateContent()
      this.updatePlaceholder()
      
      // 手动触发 input 事件，传递内容而不是事件对象
      this.$emit('input', this.content)
      this.$nextTick(() => {
        this.isInternalUpdate = false
        // 延迟更新激活状态，避免频繁查询
        this.$nextTick(() => {
          this.updateActiveStates()
        })
      })
    },
    
    // 处理键盘事件
    handleKeydown(event) {
      this.handleKeydown(event, this.readonly, this.doExecuteCommand)
    },
    
    // 处理粘贴事件
    handlePaste(event) {
      this.handlePaste(event, this.readonly)
    },
    
    // 处理焦点事件
    handleFocus() {
      this.$emit('focus')
      // 获得焦点时更新激活状态
      this.$nextTick(() => {
        this.updateActiveStates()
      })
    },
    
    // 处理失焦事件
    handleBlur() {
      this.$emit('blur',this.content)
      // 失焦时清除选择状态
      // 注意：在批注模式下，我们可能需要保留选择范围
      // 只有在非批注模式下才清除选择状态
      if (!this.showTextToolbar) {
        this.hasSelection = false
        this.selectedText = ''
        this.selectionRange = null
        this.showTextToolbar = false
      }
      // 失焦时更新激活状态
      this.$nextTick(() => {
        this.updateActiveStates()
      })
    },
    
    // 更新内容
    updateContent() {
      if (this.$refs.editor) {
        const newContent = this.$refs.editor.innerHTML
        this.content = newContent
        
        // 刷新iframe拖拽事件
        this.refreshIframeResizeEvents(this.$refs.editor, this.updateContent)
      }
    },
    
    // 更新字数统计
    updateWordCount() {
      const text = this.$refs.editor ? this.$refs.editor.textContent || '' : ''
      this.wordCount = text.length
    },
    
    // 更新占位符显示
    updatePlaceholder() {
      if (!this.$refs.editor) return
      
      const hasContent = this.$refs.editor.textContent.trim().length > 0
      
      if (hasContent) {
        this.$refs.editor.classList.remove('show-placeholder')
      } else {
        this.$refs.editor.classList.add('show-placeholder')
      }
    },
    


    
    // 处理选择开始事件
    handleSelectStart(event) {
      this.$emit('select-start', event)
    },
    
    // 处理鼠标抬起事件（选择结束）
    handleMouseUp(event) {
      
      // 检查点击的是否是工具栏
      const toolbar = event.target?.closest('.text-selection-toolbar')
      if (toolbar) {
        return // 点击工具栏时保持当前状态
      }
      
      // 延迟一点时间，确保选择已经完成
      setTimeout(() => {
        const selection = window.getSelection()
        const selectedText = selection.toString().trim()
        
        if (selectedText.length > 0) {
          
          // 检查选择是否在编辑器内
          if (selection.rangeCount > 0) {
            const range = selection.getRangeAt(0)
            if (this.$refs.editor && this.$refs.editor.contains(range.commonAncestorContainer)) {
              this.hasSelection = true
              this.selectedText = selectedText
              this.selectionRange = range.cloneRange()
              
              // 保存选择到localStorage
              this.saveSelection()
              
              // 显示文本选择工具栏
              this.showTextToolbar = true
              this.calculateToolbarPosition(range)
              
              // 触发选择变化事件
              this.$emit('selection-change', {
                hasSelection: this.hasSelection,
                selectedText: this.selectedText,
                range: this.selectionRange,
                event: event
              })
            }
          }
          
          // 触发选择结束事件
          this.$emit('select-end', {
            selectedText: selectedText,
            length: selectedText.length,
            event: event
          })
        } else {
          // 没有选择，隐藏工具栏
          this.hasSelection = false
          this.selectedText = ''
          this.selectionRange = null
          this.showTextToolbar = false
          
          // 清除保存的选择
          this.clearSavedSelection()
        }
      }, 100)
    },
    
    // 处理选择变化事件
    handleSelectionChange(event) {
      // 检查点击的是否是工具栏
      const toolbar = event.target?.closest('.text-selection-toolbar')
      if (toolbar) {
        return // 点击工具栏时保持当前状态
      }
      
      const selection = window.getSelection()
      
      if (selection.rangeCount > 0) {
        const range = selection.getRangeAt(0)
        const selectedText = selection.toString().trim()
        
        // 检查选择是否在编辑器内
        if (this.$refs.editor && this.$refs.editor.contains(range.commonAncestorContainer)) {
          this.hasSelection = selectedText.length > 0
          this.selectedText = selectedText
          this.selectionRange = range.cloneRange()
          
          // 显示或隐藏文本选择工具栏
          if (this.hasSelection && selectedText.length > 0) {
            this.showTextToolbar = true
            this.calculateToolbarPosition(range)
          } else {
            this.showTextToolbar = false
          }
          
          // 触发选择变化事件
          this.$emit('selection-change', {
            hasSelection: this.hasSelection,
            selectedText: this.selectedText,
            range: this.selectionRange,
            event: event
          })
        } else {
          // 选择不在编辑器内，清除选择状态
          this.hasSelection = false
          this.selectedText = ''
          this.selectionRange = null
          this.showTextToolbar = false
        }
      } else {
        // 没有选择
        this.hasSelection = false
        this.selectedText = ''
        this.selectionRange = null
        this.showTextToolbar = false
      }
    },
    
    // 获取当前选择的文本
    getSelectedText() {
      return this.selectedText
    },
    
    // 获取当前选择范围
    getSelectionRange() {
      return this.selectionRange
    },
    
    // 检查是否有文本被选择
    hasTextSelection() {
      return this.hasSelection
    },
    
    // 替换选中的文本
    replaceSelectedText(newText) {
      if (this.hasSelection && this.selectionRange) {
        const selection = window.getSelection()
        selection.removeAllRanges()
        selection.addRange(this.selectionRange)
        document.execCommand('insertText', false, newText)
        this.updateContent()
        return true
      }
      return false
    },
    
    // 在选中文本前后插入内容
    insertAroundSelection(beforeText, afterText) {
      if (this.hasSelection && this.selectionRange) {
        const selection = window.getSelection()
        selection.removeAllRanges()
        selection.addRange(this.selectionRange)
        
        // 插入前文本
        if (beforeText) {
          document.execCommand('insertText', false, beforeText)
        }
        
        // 恢复选择
        selection.removeAllRanges()
        selection.addRange(this.selectionRange)
        
        // 插入后文本
        if (afterText) {
          document.execCommand('insertText', false, afterText)
        }
        
        this.updateContent()
        return true
      }
      return false
    },
    
    // 计算工具栏位置
    calculateToolbarPosition(range) {
      if (!this.$refs.editor) return
      
      // 获取选中文本的最后一个字符位置
      const endRange = document.createRange()
      endRange.setStart(range.endContainer, range.endOffset)
      endRange.setEnd(range.endContainer, range.endOffset)
      const targetRect = endRange.getBoundingClientRect()
      
      // 计算工具栏位置（在最后一个字的正下方）
      // 使用fixed定位，位置相对于视口
      let x = targetRect.left
      let y = targetRect.bottom + 8 // 8px 间距
      
      // 在基础位置上调整：往下20px，往左200px
      x = x - 200
      y = y
      
      // 确保工具栏不会超出视口边界
      const toolbarWidth = 600 // 估算工具栏宽度
      const toolbarHeight = 50 // 估算工具栏高度
      
      // 检查右边界
      if (x + toolbarWidth > window.innerWidth) {
        x = window.innerWidth - toolbarWidth - 10
      }
      
      // 检查左边界
      if (x < 10) {
        x = 10
      }
      
      // 检查下边界
      if (y + toolbarHeight > window.innerHeight) {
        y = targetRect.top - toolbarHeight - 8
      }
      
      this.textToolbarPosition = { x, y }
    },
    
    // 获取选择范围内的所有文本节点
    getTextNodesInRange(range) {
      const textNodes = []
      const walker = document.createTreeWalker(
        range.commonAncestorContainer,
        NodeFilter.SHOW_TEXT,
        {
          acceptNode: function(node) {
            // 检查节点是否在选择范围内
            if (range.intersectsNode(node)) {
              return NodeFilter.FILTER_ACCEPT
            }
            return NodeFilter.FILTER_REJECT
          }
        },
        false
      )
      
      let node
      while (node = walker.nextNode()) {
        textNodes.push(node)
      }
      
      return textNodes
    },
    
    // 处理全局点击事件
    handleGlobalClick(event) {
      // 检查点击的是否是文本选择工具栏
      const textToolbar = event.target.closest('.text-selection-toolbar')
      if (textToolbar) {
        return // 点击文本选择工具栏时不隐藏
      }
      
      // 检查点击的是否是改写结果工具栏
      const rewriteToolbar = event.target.closest('.rewrite-result-toolbar')
      if (rewriteToolbar) {
        return // 点击改写结果工具栏时不隐藏
      }
      
      // 如果点击的不是编辑器内部，只隐藏工具栏，保持选择
      if (this.$refs.editor && !this.$refs.editor.contains(event.target)) {
        this.showTextToolbar = false
        this.rewriteResultVisible = false
      }
    },
    
    // 文本处理功能方法
    handleTextRewrite(data) {
      // 处理API响应数据
      if (data && data.result) {
        console.log('改写结果:', data.result)
        
        // 设置改写数据并显示弹窗
        this.rewriteData = {
          originalText: data.originalText || '',
          resultText: data.result.choices[0].message.content,
          functionType: 'rewrite'
        }
        
        // 设置改写工具栏位置（与文本选择工具栏位置相同）
        this.rewriteToolbarPosition = { ...this.textToolbarPosition }
        this.rewriteResultVisible = true
        
        // 隐藏normal-mode工具栏
        this.showTextToolbar = false
        
        // 同时发送事件给父组件
        this.$emit('text-rewrite', data)
      } else {
        this.$emit('text-rewrite', data)
      }
    },
    
    handleTextContinue(data) {
      // 处理续写结果（现在TextSelectionToolbar直接发送结果数据）
      this.handleContinueResult(data)
    },



    // 处理续写结果
    handleContinueResult(data) {
      // 处理API响应数据
      if (data && data.result) {
        console.log('续写结果:', data.result)
        
        // 设置续写数据并显示弹窗
        this.rewriteData = {
          originalText: data.originalText || '',
          resultText: data.result.choices[0].message.content,
          functionType: 'continue'
        }
        
        // 设置续写工具栏位置（与文本选择工具栏位置相同）
        this.rewriteToolbarPosition = { ...this.textToolbarPosition }
        this.rewriteResultVisible = true
        
        // 隐藏normal-mode工具栏
        this.showTextToolbar = false
        
        // 同时发送事件给父组件
        this.$emit('text-continue', data)
      } else {
        this.$emit('text-continue', data)
      }
    },
    
    handleTextAbbreviate(data) {
      // 处理缩写结果（现在TextSelectionToolbar直接发送结果数据）
      this.handleAbbreviateResult(data)
    },

    // 处理缩写结果
    handleAbbreviateResult(data) {
      // 处理API响应数据
      if (data && data.result) {
        console.log('缩写结果:', data.result)
        
        // 设置缩写数据并显示弹窗
        this.rewriteData = {
          originalText: data.originalText || '',
          resultText: data.result.choices[0].message.content,
          functionType: 'abbreviate'
        }
        
        // 设置缩写工具栏位置（与文本选择工具栏位置相同）
        this.rewriteToolbarPosition = { ...this.textToolbarPosition }
        this.rewriteResultVisible = true
        
        // 隐藏normal-mode工具栏
        this.showTextToolbar = false
        
        // 同时发送事件给父组件
        this.$emit('text-abbreviate', data)
      } else {
        this.$emit('text-abbreviate', data)
      }
    },
    
    handleTextTranslate(data) {
      // 处理翻译结果（现在TextSelectionToolbar直接发送结果数据）
      if (data && data.result) {
        this.rewriteData = {
          originalText: data.originalText || '',
          resultText: data.result.choices[0].message.content,
          functionType: 'translate'
        }
        this.rewriteToolbarPosition = { ...this.textToolbarPosition }
        this.rewriteResultVisible = true
        this.showTextToolbar = false
        this.$emit('text-translate', data)
      } else {
        this.$emit('text-translate', data)
      }
    },
    
    handleTextSpellCheck(data) {
      if (data && data.result) {
        this.rewriteData = {
          originalText: data.originalText || '',
          resultText: data.result.choices[0].message.content,
          functionType: 'smartCorrection'
        }
        this.rewriteToolbarPosition = { ...this.textToolbarPosition }
        this.rewriteResultVisible = true
        this.showTextToolbar = false
        this.$emit('text-spell-check', data)
      } else {
        this.$emit('text-spell-check', data)
      }
    },
    
    handleTextSensitiveCheck(text) {
      this.$emit('text-sensitive-check', text)
    },
    
    handleTextGrammarCheck(text) {
      this.$emit('text-grammar-check', text)
    },
    
    handleTextComment(data) {
      // 重置批注提交标志
      this.commentSubmitted = false
      // 点击批注按钮时，立即高亮选中的文本
      this.doHighlightSelectedText()
      this.$emit('text-comment', data)
    },
    
    handleCommentModeEnter() {
      // 确保工具栏在批注模式下保持可见
      this.showTextToolbar = true
    },
    
    handleCommentModeExit(data) {
      // 退出批注模式后，根据是否有选择决定是否隐藏工具栏
      if(data == '确定'){
        // 确定时不做任何处理，保留高亮
        this.showTextToolbar = false
        // 清除最近高亮元素引用，防止后续误删
        this.latestHighlightElement = null
        this.commentSubmitted = true
        return
      }else{
        // 如果已经提交过批注，不要再次移除高亮
        if (this.commentSubmitted) {
          this.showTextToolbar = false
          return
        }
        
        // 当点击取消时，直接移除最近添加的高亮元素
        this.doRemoveLatestHighlight()
        this.showTextToolbar = false
        // 清除保存的位置信息
        this.savedCommentPosition = null
      }
    },

    // 高亮选中的文本
    doHighlightSelectedText() {
      if (!this.selectionRange) {
        console.warn('没有选择范围，无法高亮文本')
        return
      }
      
      // 使用 composable 中的方法
      this.highlightSelectedText(
        this.selectionRange,
        this.updateContent,
        (position) => {
          this.savedCommentPosition = position
        }
      )
    },

    // 取消高亮选中的文本
    doRemoveHighlight() {
      if (!this.$refs.editor) {
        console.warn('编辑器未初始化')
        return
      }
      
      // 使用 composable 中的方法
      this.removeHighlight(this.$refs.editor, this.updateContent)
    },

    // 移除最近添加的高亮元素
    doRemoveLatestHighlight() {
      if (!this.$refs.editor) {
        console.warn('编辑器未初始化')
        return
      }
      
      // 使用 composable 中的方法
      this.removeLatestHighlight(this.updateContent)
    },

    // 处理批注提交
    doHandleSubmitComment(comment) {
      // 使用 composable 中的方法
      this.handleSubmitComment(
        comment,
        (rect, distanceFromTop, commentData, highlightClass, highlightColor) => {
          this.createCommentContent(rect, distanceFromTop, commentData, highlightClass, highlightColor, this.$refs.editor)
        },
        (eventName, data) => this.$emit(eventName, data)
      )
    },
    

    

    
    // 移除批注
    doRemoveComment(commentId) {
      // 使用 composable 中的方法
      this.removeComment(commentId, this.$refs.editor, this.updateContent)
    },
    

    
    // 鼠标悬停时突出显示对应的高亮区域
    doHighlightCommentArea(comment) {
      // 使用 composable 中的方法
      this.highlightCommentArea(comment, this.$refs.editor)
    },
    
    // 鼠标离开时取消突出显示
    doUnhighlightCommentArea(comment) {
      // 使用 composable 中的方法
      this.unhighlightCommentArea(comment, this.$refs.editor)
    },

    // 关闭改写结果弹窗
    closeRewriteResult() {
      this.rewriteResultVisible = false
      this.rewriteData = {
        originalText: '',
        resultText: '',
        functionType: 'rewrite'
      }
      this.rewriteToolbarPosition = { x: 0, y: 0 }
    },



    // 清除选择
    clearSelection() {
      if (window.getSelection) {
        window.getSelection().removeAllRanges()
      }
      this.hasSelection = false
      this.selectedText = ''
      this.selectionRange = null
      
      // 清除保存的选择
      this.clearSavedSelection()
    },

    // 将文本转换为HTML格式，处理换行符
    convertTextToHtml(text) {
      if (!text) return ''
      
      // 删除<think>\n\n</think>\n\n标记
      let cleanedText = text.replace(/<think>\s*\n\s*\n\s*<\/think>\s*\n\s*\n/g, '')
      
      // 转义HTML特殊字符
      const escapedText = cleanedText
        .replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')
        .replace(/"/g, '&quot;')
        .replace(/'/g, '&#39;')
      
      // 将换行符转换为<br>标签
      const htmlWithBreaks = escapedText.replace(/\n/g, '<br>')
      
      return htmlWithBreaks
    },

    // 处理应用改写结果
    handleApplyRewrite(data) {
      console.log('应用改写结果:', data)
      console.log(this.selectionRange)
      // 如果selectionRange为空，先尝试到localStorage中恢复选择
      if (!this.selectionRange) {
        this.restoreSelection()
      }
      if (this.selectionRange && data.resultText) {
        try {
          // 删除选中的文本
          this.selectionRange.deleteContents()
          
          // 将换行符转换为HTML格式
          const htmlContent = this.convertTextToHtml(data.resultText)
          
          // 创建临时容器来解析HTML
          const tempDiv = document.createElement('div')
          tempDiv.innerHTML = htmlContent
          
          // 将HTML内容插入到选择位置
          const fragment = document.createDocumentFragment()
          while (tempDiv.firstChild) {
            fragment.appendChild(tempDiv.firstChild)
          }
          this.selectionRange.insertNode(fragment)
          
          // 更新编辑器内容
          this.updateContent()
          
          // 关闭改写工具栏
          this.closeRewriteResult()
          
          // 清除选择
          this.clearSelection()
          
          // 根据功能类型显示不同的成功消息
          let successMessage = '改写已应用'
          if (data.functionType === 'continue') {
            successMessage = '续写已应用'
          } else if (data.functionType === 'abbreviate') {
            successMessage = '缩写已应用'
          }
          this.$message.success(successMessage)
        } catch (error) {
          console.error('应用结果失败:', error)
          let errorMessage = '应用改写结果失败，请重试'
          if (data.functionType === 'continue') {
            errorMessage = '应用续写结果失败，请重试'
          } else if (data.functionType === 'abbreviate') {
            errorMessage = '应用缩写结果失败，请重试'
          }
          this.$message.error(errorMessage)
        }
      }
    },

    // 处理返回到工具栏
    handleBackToToolbar() {
      console.log('返回到工具栏 - 开始')
      
      // 关闭改写结果弹窗
      this.closeRewriteResult()
      
      // 确保选择状态正确
      this.hasSelection = true
      this.showTextToolbar = true
      
      // 保持当前的选择状态并重新计算工具栏位置
      if (this.selectionRange) {
        // 重新计算工具栏位置
        this.calculateToolbarPosition(this.selectionRange)
        console.log('工具栏位置已重新计算:', this.textToolbarPosition)
      } else {
        console.warn('selectionRange 为空，无法计算工具栏位置')
      }
      
      console.log('工具栏状态:', {
        hasSelection: this.hasSelection,
        showTextToolbar: this.showTextToolbar,
        selectedText: this.selectedText
      })
      
      // this.$message.info('已返回到工具栏')
    },

    doUnhighlightCommentArea(comment) {
      // 使用 composable 中的方法
      this.unhighlightCommentArea(comment, this.$refs.editor)
    },
    
    // 滚动到高亮区域
    doScrollToHighlight(highlightElement) {
      // 使用 composable 中的方法
      this.scrollToHighlight(highlightElement, this.$refs.editor)
    },
    
    // 处理工具栏批注功能
    handleToolbarComment() {
      // 检查是否有选中的文本
      const selection = window.getSelection()
      const selectedText = selection.toString().trim()
      
      if (selectedText.length === 0) {
        // 如果没有选中文本，提示用户
        alert('请先选择要批注的文本')
        return
      }
      
      // 保存选择范围
      if (selection.rangeCount > 0) {
        this.selectionRange = selection.getRangeAt(0).cloneRange()
        this.selectedText = selectedText
        this.hasSelection = true
        
        // 显示文本选择工具栏并进入批注模式
        this.showTextToolbar = true
        this.calculateToolbarPosition(this.selectionRange)
        
        // 高亮选中的文本
        this.doHighlightSelectedText()
        
        // 延迟一点时间，确保工具栏已经显示，然后触发批注模式
        this.$nextTick(() => {
          // 设置触发批注标志
          this.triggerComment = true
          // 重置标志，避免重复触发
          this.$nextTick(() => {
            this.triggerComment = false
          })
        })
      }
    },
    
    // 处理批注显示隐藏功能
    handleToggleComments() {
      this.toggleCommentsVisibility()
    },
    
    // 处理编辑器滚动事件
    handleEditorScroll() {
      if (!this.$refs.editor || this.comments.length === 0) return
      
      const currentScrollTop = this.$refs.editor.scrollTop
      const scrollDelta = currentScrollTop - this.lastScrollTop
      
      // 更新所有批注的位置
      this.comments.forEach(comment => {
        if (comment.style.top) {
          // 获取当前top值（去掉px单位）
          const currentTop = parseInt(comment.style.top)
          // 根据滚动方向调整位置
          // 向下滚动（scrollDelta > 0）时，批注向上移动
          // 向上滚动（scrollDelta < 0）时，批注向下移动
          const newTop = currentTop - scrollDelta
          comment.style.top = `${newTop}px`
        }
      })
      
      // 更新上次滚动位置
      this.lastScrollTop = currentScrollTop
    },

         // 处理编辑器点击事件
     handleEditorClick(event) {
       // 检查点击的是否是工具栏
       const toolbar = event.target.closest('.text-selection-toolbar')
       if (toolbar) {
         return // 点击工具栏时不处理
       }

       // 检查点击的是否是批注内容
       const commentContent = event.target.closest('.comment-content')
       if (commentContent) {
         return // 点击批注内容时不处理
       }

       // 检查点击的是否是变量
       const variableElement = event.target.closest('.editor-variable')
       if (variableElement) {
         const variableId = variableElement.getAttribute('data-variable-id') || variableElement.id
         if (variableId) {
           console.log('点击了变量:', variableId)
           this.$emit('variable-click', variableId)
         }
         return // 点击变量时不处理
       }

       // 如果点击的是编辑器内部，尝试恢复选择
       if (this.$refs.editor && this.$refs.editor.contains(event.target)) {
         if (this.savedSelection && !this.hasSelection) {
           this.restoreSelection()
         }
       }
     },

    // 保存选择到localStorage
    saveSelection() {
      if (this.selectedText && this.selectionRange) {
        const selectionData = {
          text: this.selectedText,
          startOffset: this.selectionRange.startOffset,
          endOffset: this.selectionRange.endOffset,
          startContainer: this.selectionRange.startContainer.textContent,
          endContainer: this.selectionRange.endContainer.textContent
        }
        localStorage.setItem('editor_selection', JSON.stringify(selectionData))
        this.savedSelection = selectionData
      }
    },

    // 从localStorage恢复选择
    restoreSelection() {
      const saved = localStorage.getItem('editor_selection')
      if (saved && this.$refs.editor) {
        try {
          const data = JSON.parse(saved)
          // 简单的文本匹配恢复
          const textNodes = this.getAllTextNodes(this.$refs.editor)
          for (let node of textNodes) {
            if (node.textContent.includes(data.text)) {
              const range = document.createRange()
              const startIndex = node.textContent.indexOf(data.text)
              range.setStart(node, startIndex)
              range.setEnd(node, startIndex + data.text.length)
              
              this.selectionRange = range
              this.selectedText = data.text
              this.hasSelection = true
              this.showTextToolbar = true
              this.calculateToolbarPosition(range)
              
              // 恢复选择
              const selection = window.getSelection()
              selection.removeAllRanges()
              selection.addRange(range)
              break
            }
          }
        } catch (e) {
          console.error('恢复选择失败:', e)
        }
      }
    },

    // 清除保存的选择
    clearSavedSelection() {
      localStorage.removeItem('editor_selection')
      this.savedSelection = null
    },

    // 获取所有文本节点
    getAllTextNodes(element) {
      const textNodes = []
      const walker = document.createTreeWalker(
        element,
        NodeFilter.SHOW_TEXT,
        null,
        false
      )
      
      let node
      while (node = walker.nextNode()) {
        textNodes.push(node)
      }
      
      return textNodes
    }
  }
}
</script>

<style scoped>
@import './font/iconfont.css';
.rich-text-editor {
  border: 1px solid #ddd;
  border-radius: 4px;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  display: flex;
  flex-direction: column;
  height: 100%;
  position: relative;
  /* overflow: hidden; */
}

.toolbar {
  display: flex;
  align-items: center;
  padding: 8px 12px;
  background: #ffffff;
  border-bottom: 1px solid #e5e7eb;
  flex-wrap: wrap;
  gap: 8px;
  flex-shrink: 0;
}

.toolbar-group {
  display: flex;
  align-items: center;
  gap: 4px;
}

.group-tools {
  display: flex;
  align-items: center;
  gap: 2px;
}

.group-separator {
  width: 1px;
  height: 20px;
  background: #d1d5db;
  margin: 0 4px;
}

.tool-btn {
  padding: 8px;
  border: none;
  background: transparent;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
  min-width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.15s ease;
  color: #6b7280;
  user-select: none;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  position: relative;
}

.tool-btn:hover {
  background: #f3f4f6;
  color: #374151;
  transform: translateY(-1px);
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.tool-btn:active {
  transform: translateY(0);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}

.tool-btn.active {
  background: #e5e7eb;
  color: #111827;
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1);
}

/* 录音相关样式 */
.tool-btn.recording {
  background: #6bbced !important;
  color: white !important;
  animation: recording-pulse 1.5s ease-in-out infinite;
}

.tool-btn.recording i {
  color: white !important;
}

.tool-btn.processing {
  background: #f8ac36 !important;
  color: white !important;
}

.tool-btn.processing i {
  color: white !important;
}

.tool-btn.disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.tool-btn.disabled:hover {
  background: transparent;
}

/* 波浪动效 */
.wave-animation {
  position: absolute;
  bottom: 1vh;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 1px;
  height: 8px;
}

.wave-bar {
  width: 2px;
  height: 4px;
  background: white;
  border-radius: 1px;
  animation: wave 1.2s ease-in-out infinite;
}

.wave-bar:nth-child(1) { animation-delay: 0s; }
.wave-bar:nth-child(2) { animation-delay: 0.1s; }
.wave-bar:nth-child(3) { animation-delay: 0.2s; }
.wave-bar:nth-child(4) { animation-delay: 0.3s; }
.wave-bar:nth-child(5) { animation-delay: 0.4s; }

@keyframes wave {
  0%, 100% {
    height: 4px;
  }
  50% {
    height: 8px;
  }
}

@keyframes recording-pulse {
  0%, 100% {
    box-shadow: 0 0 0 0 rgba(54, 208, 255, 0.7);
  }
  50% {
    box-shadow: 0 0 0 4px rgba(255, 172, 54, 0);
  }
}

/* 解析状态指示器 */
.processing-indicator {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 20px;
  height: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.processing-indicator::before {
  content: '';
  width: 16px;
  height: 16px;
  border: 2px solid transparent;
  border-top: 2px solid #f8ac36;
  border-radius: 50%;
  animation: processing-spin 1s linear infinite;
}

.processing-indicator i {
  display: none;
}

@keyframes processing-spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}



.color-picker,
.bg-color-picker {
  padding: 6px 8px;
  border: 1px solid #d1d5db;
  border-radius: 4px;
  font-size: 12px;
  background: #ffffff;
  color: #374151;
  transition: all 0.2s ease;
}

.color-picker:hover,
.bg-color-picker:hover {
  border-color: #9ca3af;
}

.color-picker,
.bg-color-picker {
  width: 32px;
  height: 32px;
  padding: 2px;
  cursor: pointer;
  border-radius: 4px;
  border: 1px solid #d1d5db;
}

.color-picker::-webkit-color-swatch-wrapper,
.bg-color-picker::-webkit-color-swatch-wrapper {
  border-radius: 2px;
  overflow: hidden;
}

.color-picker::-webkit-color-swatch,
.bg-color-picker::-webkit-color-swatch {
  border: none;
  border-radius: 2px;
}

.editor-content {
  flex: 1;
  min-height: 0;
  padding: 12px;
  outline: none;
  line-height: 1.6;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  position: relative;
}

.editor-content.show-placeholder:before {
  content: attr(data-placeholder);
  color: #999;
  pointer-events: none;
  position: absolute;
  top: 12px;
  left: 12px;
}

.editor-content[contenteditable="false"] {
  background: #f8f9fa;
  cursor: not-allowed;
}

.word-count {
  padding: 8px 12px;
  background: #f9fafb;
  border-top: 1px solid #e5e7eb;
  font-size: 12px;
  color: #6b7280;
  text-align: right;
  flex-shrink: 0;
}

/* 编辑器内容样式 */
.editor-content :deep(h1) {
  font-size: 24px;
  margin: 16px 0 8px 0;
}

.editor-content :deep(h2) {
  font-size: 20px;
  margin: 14px 0 6px 0;
}

.editor-content :deep(h3) {
  font-size: 18px;
  margin: 12px 0 6px 0;
}

.editor-content :deep(p) {
  margin: 8px 0;
}

.editor-content :deep(ul),
.editor-content :deep(ol) {
  margin: 8px 0;
  padding-left: 20px;
}

.editor-content :deep(li) {
  margin: 4px 0;
}

.editor-content :deep(a) {
  color: #007bff;
  text-decoration: underline;
}

.editor-content :deep(img) {
  max-width: 100%;
  height: auto;
  margin: 8px 0;
}

.editor-content :deep(blockquote) {
  border-left: 4px solid #ddd;
  margin: 8px 0;
  padding-left: 12px;
  color: #666;
}

.editor-content :deep(table) {
  border-collapse: collapse;
  width: 100%;
  margin: 8px 0;
  border: 1px solid #ddd;
}

.editor-content :deep(table td),
.editor-content :deep(table th) {
  border: 1px solid #ddd;
  padding: 8px;
  text-align: left;
  vertical-align: top;
}

.editor-content :deep(table th) {
  background-color: #f8f9fa;
  font-weight: 600;
}

.editor-content :deep(table tr:nth-child(even)) {
  background-color: #f9f9f9;
}

.editor-content :deep(table tr:hover) {
  background-color: #f5f5f5;
}

.editor-content :deep(iframe) {
  max-width: 100%;
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  margin: 12px 0;
  display: block;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
  transition: box-shadow 0.2s ease;
}

.editor-content :deep(iframe:hover) {
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
}

/* iframe拖拽调整大小样式 */
.editor-content :deep(iframe.resizing) {
  outline: 2px dashed #007bff !important;
  outline-offset: 2px;
}

/* 确保编辑器容器有相对定位 */
.editor-content {
  position: relative;
}

/* 确保iframe有相对定位，便于拖拽操作 */
.editor-content :deep(iframe) {
  position: relative;
}
.color-btn-wrapper {
  display: inline-block;
  margin-right: 4px;
}
.color-btn {
  background: #fff;
  border: none;
  font-size: 18px;
  cursor: pointer;
  border-radius: 4px 4px 0 0;
  position: relative;
  height: 32px;
  min-width: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.text-color-btn i {
  color: #333;
}
.bg-color-btn i {
  color: #333;
}
.color-btn:focus {
  outline: 2px solid #007bff;
}
.color-input-overlay {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
  border: none;
  padding: 0;
  margin: 0;
}

/* 高亮样式 */
.editor-content :deep(.comment-highlight) {
  color: #000 !important;
  padding: 2px 4px;
  border-radius: 3px;
  display: inline;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
  transition: all 0.2s ease;
}

/* 高亮元素的悬停效果 */
.editor-content :deep(.comment-highlight:hover) {
  transform: scale(1.02);
  box-shadow: 0 0 0 1px rgba(0, 123, 255, 0.3);
}

/* 批注内容样式 */
.comment-content {
  position: absolute;
  background: #fff;
  border: 1px solid #ddd;
  border-radius: 4px;
  padding: 8px;
  width: 15.6vw;
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
  z-index: 1000;
  font-size: 12px;
  line-height: 1.4;
  pointer-events: auto;
  transition: all 0.3s ease;
}

.comment-content:hover {
  box-shadow: 0 4px 12px rgba(0,0,0,0.15);
  transform: translateY(-1px);
  cursor: pointer;
}

.comment-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 6px;
  padding-bottom: 4px;
  border-bottom: 1px solid #EBEBEB;
}

.comment-info {
  display: flex;
  align-items: center;
  gap: 6px;
}

.color-indicator {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  border: 1px solid #ddd;
  flex-shrink: 0;
  transition: all 0.2s ease;
}

.comment-meta {
  width: 13vw;
  justify-content: space-between;
  display: flex;
  align-items: center;
  gap: 2px;
  font-size: 11px;
  color: #666;
}

.comment-username {
  color: #2B2B2B;
  font-size: .8vw;
}

.comment-time {
  color: #666;
  font-size: .7vw;
}

.comment-close {
  background: none;
  border: none;
  color: #999;
  font-size: 16px;
  cursor: pointer;
  padding: 0;
  width: 16px;
  height: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 2px;
}

.comment-close:hover {
  background: #f0f0f0;
  color: #666;
}

.comment-text {
  color: #2B2B2B;
  word-wrap: break-word;
  font-size: .8vw;
}

/* 变量样式 */
.editor-content :deep(.editor-variable) {
  background-color: rgba(255, 193, 7, 0.1);
  border: 1px solid rgba(255, 193, 7, 0.3);
  border-radius: 3px;
  padding: 1px 3px;
  color: #e6a23c;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.2s ease;
  display: inline-block;
}

.editor-content :deep(.editor-variable:hover) {
  background-color: rgba(255, 193, 7, 0.2);
  border-color: rgba(255, 193, 7, 0.5);
  transform: scale(1.05);
  box-shadow: 0 2px 4px rgba(255, 193, 7, 0.2);
}

/* 变量高亮样式 */
.editor-content :deep(.editor-variable.variable-highlight) {
  background-color: rgba(64, 158, 255, 0.2) !important;
  border: 2px solid #409eff !important;
  border-radius: 4px !important;
  padding: 2px 4px !important;
  box-shadow: 0 0 8px rgba(64, 158, 255, 0.4) !important;
  animation: variablePulse 1.5s ease-in-out infinite;
  color: #409eff !important;
  font-weight: 600 !important;
}

@keyframes variablePulse {
  0%, 100% {
    box-shadow: 0 0 8px rgba(64, 158, 255, 0.4);
  }
  50% {
    box-shadow: 0 0 12px rgba(64, 158, 255, 0.6);
  }
}

</style>